﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.IO;

namespace LiquifierTest
{
    #region MemoryTributary Tests

    [TestClass()]
    public class MemoryTributaryTest
    {
        [TestMethod()]
        public void MemoryTributary_Basic_Tests()
        {
            MemoryTributary t = new MemoryTributary();
            int l;
            byte[] garbage = new byte[32000];

            l = WriteBytes(t, 0xF, 10);
            t.Position = 0;
            t.Read(garbage, 0, 9);
            Assert.AreEqual(t.Length, l);

            t.Position = 0;
            l = WriteBytes(t, 0xFF, 10000000);
            t.Position -= 6556;
            t.Read(garbage, 0, 6556);
            Assert.AreEqual(t.Length, l);

            l += WriteBytes(t, 0x55, 123003);
            t.Position -= 12344;
            t.Read(garbage, 0, 1234);
            Assert.AreEqual(t.Length, l);

        }

        [TestMethod()]
        public void MemoryTributary_Large_Dataset_Test()
        {
            long onemb = 1024 * 1024;
            long onehundredmb = onemb * 100;
            long fivehundredmb = onemb * 500;
            long onegigabyte = onemb * 1024;

            byte[] randdata = new byte[32000];

            MemoryTributary d = new MemoryTributary();

            WriteGarbage(randdata, onemb, d);
            WriteGarbage(randdata, onehundredmb, d);
            WriteGarbage(randdata, fivehundredmb, d);

            if (IntPtr.Size > 4)    //if we are on x64
            {
                WriteGarbage(randdata, onegigabyte, d);
            }
        }

        [TestMethod()]
        public void MemoryTributary_WierdStuff()
        {
            ////A new MemoryTributary object: length is 0, position is 0, no memory has been allocated
            MemoryTributary d = new MemoryTributary();

            ////returns -1 because Length is 0, no memory allocated
            //int a = d.ReadByte();

            ////Length now reports 10000 bytes, but no memory is allocted
            //d.SetLength(10000);

            ////three blocks of memory are now allocated, b is undefined because they have not been initialised
            //int b = d.ReadByte();   


            Assert.AreEqual(d.Length, 0);

            d.SetLength(20000);

            Assert.AreEqual(d.Length, 20000);

            d.Position = 15000;
            d.ReadByte();

            d.Position = 25000;
            Assert.AreEqual(d.Length, 20000);

            d.WriteByte(0xFF);
            Assert.AreEqual(d.Length, 25001);
        }

        public void WriteGarbage(byte[] garbage, long targetamount, MemoryTributary d)
        {
            long cnt = targetamount / garbage.Length;

            for (int i = 0; i < cnt; i++)
            {
                WriteData(d, garbage, 1);
            }
        }

        public int WriteBytes(MemoryTributary d, byte val, int len)
        {
            for (int i = 0; i < len; i++)
            {
                d.WriteByte(val);
            }
            return len;
        }

        public int WriteData(MemoryTributary d, byte[] data, int len)
        {
            for (int i = 0; i < len; i++)
            {
                d.Write(data, 0, data.Length);
            }
            return data.Length * len;
        }

    }

    #endregion
}
